use sled::transaction::{ConflictableTransactionError, TransactionError};
use thiserror::Error;

use aspect_db_mq_types::{Error, QueueId, ReaderId, SanityError};

#[derive(Debug, Error)]
pub enum DbError {
    #[error("queue: {0}")]
    Queue(#[from] Error),

    #[error("db: {0}")]
    Sled(#[from] sled::Error),
}

impl From<aspect_codec::CodecError> for DbError {
    fn from(value: aspect_codec::CodecError) -> Self {
        Error::from(value).into()
    }
}

impl From<SanityError> for DbError {
    fn from(value: SanityError) -> Self {
        Error::from(value).into()
    }
}

impl From<TransactionError<Error>> for DbError {
    fn from(value: TransactionError<Error>) -> Self {
        match value {
            TransactionError::Abort(e) => Self::Queue(e),
            TransactionError::Storage(e) => Self::Sled(e),
        }
    }
}

pub fn into_cte<E: Into<Error>>(e: E) -> ConflictableTransactionError<Error> {
    ConflictableTransactionError::Abort(e.into())
}
